import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:developer' as developer;
import '../models/call_invite.dart';
import '../models/friend_model.dart';
import '../repositories/friend_repository.dart';
import '../repositories/chat_repository.dart';
import '../di/service_locator.dart';
import '../../features/chat/pages/video_call_page.dart';
import '../../shared/widgets/call_invite_dialog.dart';

/// 全局通话管理服务
/// 负责处理所有通话邀请、接听、挂断等操作
class CallManagerService {
  static final CallManagerService _instance = CallManagerService._internal();
  factory CallManagerService() => _instance;
  CallManagerService._internal();

  GlobalKey<NavigatorState>? _navigatorKey;
  StreamSubscription? _websocketSubscription;
  final Map<String, CallInvite> _activeInvites = {}; // 当前活跃的通话邀请
  final Set<String> _showingDialogs = {}; // 正在显示的对话框（避免重复显示）
  String? _currentUserId;
  List<FriendModel> _friends = [];

  /// 初始化服务
  Future<void> init(GlobalKey<NavigatorState> navigatorKey) async {
    _navigatorKey = navigatorKey;
    
    // 获取当前用户ID
    await _updateCurrentUserId();
    
    // 监听 WebSocket 消息
    _setupWebSocketListener();
    
    // 加载好友列表（用于显示通话邀请时的用户信息）
    _loadFriends();
    
    developer.log('通话管理服务已初始化', name: 'CallManagerService');
  }

  /// 更新当前用户ID
  Future<void> _updateCurrentUserId() async {
    try {
      final serviceLocator = ServiceLocator();
      final storageService = serviceLocator.storageService;
      final userStr = await storageService.getUserInfo();
      if (userStr != null && userStr.isNotEmpty) {
        final user = jsonDecode(userStr) as Map<String, dynamic>;
        _currentUserId = user['open_id']?.toString() ?? 
                        user['openId']?.toString() ?? 
                        (user['snowflake_id'] != null ? user['snowflake_id'].toString() : null) ??
                        (user['id'] != null ? user['id'].toString() : null);
      }
    } catch (e) {
      developer.log('获取当前用户ID失败: $e', name: 'CallManagerService');
    }
  }

  /// 加载好友列表
  Future<void> _loadFriends() async {
    try {
      final serviceLocator = ServiceLocator();
      final friendRepository = serviceLocator.friendRepository;
      final response = await friendRepository.getFriends();
      if (response.success && response.data != null) {
        _friends = response.data!;
        developer.log('好友列表已加载: ${_friends.length} 个好友', name: 'CallManagerService');
      }
    } catch (e) {
      developer.log('加载好友列表失败: $e', name: 'CallManagerService');
    }
  }

  /// 设置 WebSocket 监听
  void _setupWebSocketListener() {
    // 如果已经监听，先取消
    _websocketSubscription?.cancel();
    
    final serviceLocator = ServiceLocator();
    final webSocketService = serviceLocator.webSocketService;
    
    _websocketSubscription = webSocketService.messageStream.listen(
      (message) {
        _handleWebSocketMessage(message);
      },
      onError: (error) {
        developer.log('WebSocket stream error in CallManagerService: $error', name: 'CallManagerService');
      },
      onDone: () {
        developer.log('WebSocket stream closed in CallManagerService', name: 'CallManagerService');
        // WebSocket 关闭后，尝试重新监听（如果服务还在运行）
        if (_navigatorKey != null) {
          Future.delayed(const Duration(seconds: 2), () {
            if (_navigatorKey != null) {
              _setupWebSocketListener();
            }
          });
        }
      },
      cancelOnError: false,
    );
    
    developer.log('WebSocket 监听器已设置', name: 'CallManagerService');
  }

  /// 处理 WebSocket 消息
  void _handleWebSocketMessage(dynamic message) {
    try {
      // 解析消息
      Map<String, dynamic>? messageMap;
      if (message is Map<String, dynamic>) {
        messageMap = message;
      } else if (message is String) {
        try {
          messageMap = jsonDecode(message) as Map<String, dynamic>;
        } catch (e) {
          return;
        }
      } else {
        return;
      }

      // 检查是否是状态消息
      if (messageMap['type'] == 'status') {
        return;
      }

      // 提取消息内容
      final messageContent = messageMap['message']?.toString() ?? messageMap['message_body']?.toString() ?? '';
      final messageContentType = messageMap['message_content_type'] ?? messageMap['message_type'];
      
      // 检查是否是通话邀请消息
      final isCallInviteByType = messageContentType == 4;
      bool isCallInviteByContent = false;
      Map<String, dynamic>? inviteData;
      
      if (messageContent.isNotEmpty) {
        try {
          final parsed = jsonDecode(messageContent) as Map<String, dynamic>?;
          if (parsed != null && parsed['type'] == 'call_invite') {
            isCallInviteByContent = true;
            inviteData = parsed;
          }
        } catch (e) {
          // 不是 JSON，忽略
        }
      }

      if (isCallInviteByType || isCallInviteByContent || messageMap['type'] == 'call_invite') {
        _handleCallInvite(messageMap, inviteData);
        return;
      }

      // 检查是否是通话取消消息
      final isCallCancelByType = messageContentType == 5;
      bool isCallCancelByContent = false;
      if (messageContent.isNotEmpty) {
        try {
          final parsed = jsonDecode(messageContent) as Map<String, dynamic>?;
          if (parsed != null && parsed['type'] == 'call_cancel') {
            isCallCancelByContent = true;
          }
        } catch (e) {
          // 不是 JSON，忽略
        }
      }

      if (isCallCancelByType || isCallCancelByContent || messageMap['type'] == 'call_cancel') {
        _handleCallCancel(messageMap);
        return;
      }
    } catch (e) {
      developer.log('处理 WebSocket 消息失败: $e', name: 'CallManagerService');
    }
  }

  /// 处理通话邀请
  void _handleCallInvite(Map<String, dynamic> messageMap, Map<String, dynamic>? inviteDataFromContent) {
    try {
      developer.log('收到通话邀请消息（全局服务）', name: 'CallManagerService');
      
      // 更新当前用户ID
      _updateCurrentUserId();
      
      // 检查是否是发送给当前用户的
      final toUserId = messageMap['to_user_id']?.toString() ?? messageMap['to_id']?.toString();
      if (_currentUserId == null || toUserId == null || toUserId != _currentUserId) {
        developer.log('通话邀请不是发送给当前用户的，忽略', name: 'CallManagerService');
        return;
      }

      // 提取邀请数据
      Map<String, dynamic> inviteData;
      if (inviteDataFromContent != null) {
        inviteData = inviteDataFromContent;
      } else if (messageMap['type'] == 'call_invite') {
        inviteData = messageMap;
      } else {
        final messageContent = messageMap['message']?.toString() ?? messageMap['message_body']?.toString() ?? '';
        if (messageContent.isNotEmpty) {
          try {
            inviteData = jsonDecode(messageContent) as Map<String, dynamic>;
          } catch (e) {
            developer.log('无法解析通话邀请内容: $e', name: 'CallManagerService');
            return;
          }
        } else {
          developer.log('通话邀请消息缺少内容', name: 'CallManagerService');
          return;
        }
      }

      // 检查邀请是否已过期
      final timestamp = inviteData['timestamp'] ?? messageMap['timestamp_ms'] ?? messageMap['timestamp'];
      final timeout = inviteData['timeout'] ?? 30;
      final messageTimestamp = timestamp is int ? timestamp : DateTime.now().millisecondsSinceEpoch;
      
      final now = DateTime.now().millisecondsSinceEpoch;
      final expireTime = messageTimestamp + (timeout * 1000);
      if (now > expireTime) {
        developer.log('通话邀请已过期，忽略', name: 'CallManagerService');
        return;
      }

      // 获取发送者信息
      final fromUserId = messageMap['from_user_id']?.toString() ?? messageMap['from_id']?.toString();
      if (fromUserId == null) {
        developer.log('通话邀请消息缺少发送者ID', name: 'CallManagerService');
        return;
      }

      // 从好友列表中查找发送者信息
      FriendModel? friend;
      try {
        friend = _friends.firstWhere(
          (f) => f.openId == fromUserId || 
                 f.username == fromUserId ||
                 f.userId.toString() == fromUserId,
        );
      } catch (e) {
        // 如果找不到好友，创建一个临时的
        friend = FriendModel(
          id: 0,
          userId: 0,
          username: fromUserId,
          status: 1,
        );
      }

      // 创建通话邀请对象
      final callInvite = CallInvite(
        fromUserId: fromUserId,
        fromUserName: friend.displayName,
        isVoiceOnly: inviteData['isVoiceOnly'] ?? inviteData['is_voice_only'] ?? false,
        messageId: messageMap['message_id']?.toString() ?? DateTime.now().millisecondsSinceEpoch.toString(),
        timeout: timeout,
        timestamp: messageTimestamp,
      );

      // 检查是否已有相同的邀请（避免重复显示）
      if (_activeInvites.containsKey(callInvite.messageId) || 
          _showingDialogs.contains(callInvite.messageId)) {
        developer.log('通话邀请已存在或正在显示，忽略重复邀请', name: 'CallManagerService');
        return;
      }

      // 保存邀请
      _activeInvites[callInvite.messageId] = callInvite;
      _showingDialogs.add(callInvite.messageId);

      // 显示接听对话框
      _showCallInviteDialog(callInvite, friend);
    } catch (e) {
      developer.log('处理通话邀请失败: $e', name: 'CallManagerService');
    }
  }

  /// 显示通话邀请对话框
  void _showCallInviteDialog(CallInvite invite, FriendModel? friend) {
    if (_navigatorKey?.currentContext == null) {
      developer.log('Navigator context 不可用，无法显示通话邀请对话框', name: 'CallManagerService');
      return;
    }

    final context = _navigatorKey!.currentContext!;
    
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => CallInviteDialog(
        invite: invite,
        friend: friend,
        onAccept: () {
          Navigator.of(context).pop(); // 关闭对话框
          _acceptCall(invite);
          _activeInvites.remove(invite.messageId);
          _showingDialogs.remove(invite.messageId);
        },
        onReject: () {
          Navigator.of(context).pop(); // 关闭对话框
          developer.log('用户拒绝通话邀请', name: 'CallManagerService');
          _activeInvites.remove(invite.messageId);
          _showingDialogs.remove(invite.messageId);
        },
      ),
    ).then((_) {
      // 对话框关闭时（超时或其他原因），清理状态
      _activeInvites.remove(invite.messageId);
      _showingDialogs.remove(invite.messageId);
    });
  }

  /// 接听通话
  void _acceptCall(CallInvite invite) {
    developer.log('接听通话: ${invite.isVoiceOnly ? "语音" : "视频"}', name: 'CallManagerService');
    
    if (_navigatorKey?.currentContext == null || _currentUserId == null) {
      developer.log('无法接听通话：Navigator context 或用户ID不可用', name: 'CallManagerService');
      return;
    }

    final context = _navigatorKey!.currentContext!;
    
    // 导航到视频通话页面（接听模式）
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => VideoCallPage(
          targetUserId: invite.fromUserId,
          targetName: invite.fromUserName,
          currentUserId: _currentUserId!,
          isVoiceOnly: invite.isVoiceOnly,
        ),
      ),
    );
  }

  /// 处理通话取消
  void _handleCallCancel(Map<String, dynamic> messageMap) {
    try {
      developer.log('收到通话取消消息（全局服务）', name: 'CallManagerService');
      
      final fromUserId = messageMap['from_user_id']?.toString() ?? messageMap['from_id']?.toString();
      final messageId = messageMap['message_id']?.toString();
      
      // 移除对应的邀请
      if (messageId != null && _activeInvites.containsKey(messageId)) {
        _activeInvites.remove(messageId);
        developer.log('已移除通话邀请: $messageId', name: 'CallManagerService');
      }
      
      // 如果当前正在通话，可以在这里处理挂断逻辑
      // TODO: 实现通话中的挂断处理
    } catch (e) {
      developer.log('处理通话取消失败: $e', name: 'CallManagerService');
    }
  }

  /// 刷新好友列表（用户登录后调用）
  Future<void> refreshFriends() async {
    await _loadFriends();
    await _updateCurrentUserId();
  }

  /// 清理资源
  void dispose() {
    _websocketSubscription?.cancel();
    _activeInvites.clear();
    _showingDialogs.clear();
    developer.log('通话管理服务已清理', name: 'CallManagerService');
  }
}

